#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

// 得到指定线程的调度策略
int GetThreadPolicyFunc(pthread_attr_t *pAttr)
{
    int  iPolicy = 0;
    int ret = pthread_attr_getschedpolicy(pAttr,&iPolicy);
    assert(ret == 0);
    switch(iPolicy)
    {
        case SCHED_OTHER:
            printf("Policy is -> SCHED_OTHER.\n");
            break;
        case SCHED_FIFO:
            printf("Policy is -> SCHED_FIFO.\n");
            break;
        case SCHED_RR:
            printf("Policy is -> SCHED_RR.\n");
            break;
        default:
            printf("Policy is -> Unknown.\n");
    }
    return iPolicy;
}

// 得到调度策略iPolicy的最大最小优先级
void PrintMaxMinPriorityFunc(int iPolicy)
{
    int iPriority = sched_get_priority_max(iPolicy);
    assert(iPriority != -1);
    printf("max priority is -> %d.\n",iPriority);

    iPriority = sched_get_priority_min(iPolicy);
    assert(iPriority != -1);
    printf("min priority is -> %d.\n",iPriority);
}

// 获取指定线程的优先级
int GetThreadPriorityFunc(pthread_attr_t *pAttr)
{
    struct sched_param sParam;
    int irs = pthread_attr_getschedparam(pAttr,&sParam);
    assert(irs == 0);

    printf("Priority=%d\n",sParam.__sched_priority);
    return sParam.__sched_priority;
}

// 设置指定线程的优先级
int SetThreadPriorityFunc(pthread_attr_t *pAttr,int priority)
{
    struct sched_param sParam;
    sParam.__sched_priority = priority;
    int irs = pthread_attr_setschedparam(pAttr,&sParam);
    assert(irs == 0);

    int _priority = GetThreadPriorityFunc(pAttr);
    assert(priority==_priority);
    return _priority;
}

// 设置指定线程的调度策略为iPolicy
void SetThreadPolicyFunc(pthread_attr_t *pAttr, int iPolicy)
{
    int irs = pthread_attr_setschedpolicy(pAttr,iPolicy);
    assert(irs == 0);
    GetThreadPolicyFunc(pAttr);
}

int main()
{
    pthread_attr_t pAttr;
    struct sched_param schedParam;

    int irs = pthread_attr_init(&pAttr);
    assert(irs == 0);

    printf("\nExport priority of current thread.\n");
    int iPriority = GetThreadPriorityFunc(&pAttr);

    int iPolicy = GetThreadPolicyFunc(&pAttr);

    printf("\nExport current configuration of priority.\n");
    PrintMaxMinPriorityFunc(iPolicy);

    printf("\nExport SCHED_FIFO of priority.\n");
    PrintMaxMinPriorityFunc(SCHED_FIFO);

    printf("\nExport SCHED_RR of priority.\n");
    PrintMaxMinPriorityFunc(SCHED_RR);

    printf("\nExport priority of current thread.\n");
    iPriority = GetThreadPriorityFunc(&pAttr);
    
    printf("\nSet SCHED_FIFO policy.\n");
    SetThreadPolicyFunc(&pAttr,SCHED_FIFO);

    printf("\nExport priority of current thread.\n");
    iPriority = GetThreadPriorityFunc(&pAttr);

    printf("\nSet priority is 99.\n");
    SetThreadPriorityFunc(&pAttr,99);

    printf("\nExport priority of current thread.\n");
    iPriority = GetThreadPriorityFunc(&pAttr);

    printf("\nRestore current policy.\n");
    SetThreadPolicyFunc(&pAttr,iPolicy);

    irs = pthread_attr_destroy(&pAttr);
    assert(irs==0);

    return 0;
}